package com.bdqn.business.access.service;

import com.bdqn.base.BaseService;
import com.bdqn.business.access.dao.DepartmentRepository;
import com.bdqn.business.access.dao.TeacherRepository;
import com.bdqn.entity.access.Department;
import com.bdqn.entity.access.Teacher;
import com.bdqn.response.Result;
import com.bdqn.response.ResultCode;
import com.bdqn.utils.IdWorker;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class DepartmentService extends BaseService {

    @Autowired
    private DepartmentRepository departmentRepository;

    @Autowired
    private TeacherRepository teacherRepository;

    @Autowired
    private IdWorker idWorker;

    @CachePut(cacheNames = "department",key = "#department.id")
    public Result saveDepartment(Department department) {
        department.setCreateTime(new Date());
        department.setId(idWorker.nextId());
        department.setModifyId(currentUser().getId());
        department.setModifyUser(currentUser().getNickName());
        department.setModifyTime(new Date());
        departmentRepository.save(department);
        return new Result(ResultCode.SUCCESS,department);
    }

    @CachePut(cacheNames = "department",key = "#department.id")
    public Result updateDepartment(Department department) {
        Department target = departmentRepository.findById(department.getId()).get();
        BeanUtils.copyProperties(department,target);

        target.setModifyId(currentUser().getId());
        target.setModifyUser(currentUser().getNickName());
        target.setModifyTime(new Date());
        departmentRepository.save(target);

        return new Result(ResultCode.SUCCESS,target);
    }


    @CacheEvict(cacheNames = "department",key = "#id")
    public Result removeDepartment(String id) {

        List<Teacher> list = teacherRepository.findByDepartmentId(id);

        if(list != null && list.size() > 0) return new Result(ResultCode.FAIL);

        departmentRepository.deleteById(id);

        return Result.SUCCESS();
    }

    public Result findAll() {
        List<Department> departments =  this.getDepartments("0");
        return new Result(ResultCode.SUCCESS,departments);
    }

    private List<Department> getDepartments(String pid) {
        List<Department> list = new ArrayList<>();
        Specification<Department> specification = new Specification<Department>() {
            @Override
            public Predicate toPredicate(Root<Department> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<>();

                list.add(criteriaBuilder.equal(root.get("pid").as(String.class),pid));

                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        };

        List<Department> departments = departmentRepository.findAll(specification);

        if(departments != null && departments.size() > 0){
            for (Department department : departments) {
                department.setChildren(this.getDepartments(department.getId()));
                list.add(department);
            }
        }

        return list;
    }




}
